package com.ada.demo

object Basic {
  def main(args: Array[String]): Unit = {
    val name = "ApacheCN"
    val age = 11
    val url = "www.ada.com"
    //字符串通过+号连接（类似java）
    println("name=" + name + " age=" + age + " url=" + url) //name=ApacheCN age=11 url=www.ada.com
    //printf用法 （类似C语言）字符串通过 % 传值。(格式化输出)
    printf("name=%s, age=%d, url=%s \n", name, age, url) //name=ApacheCN, age=11, url=www.ada.com
    //字符串插值：通过$引用(类似PHP）
    println(s"name=$name, age=$age, url=$url") //name=ApacheCN, age=11, url=www.ada.com
    //格式化输出
    println(f"name=${name}, age=${age}%.2f, url=${url}") //name=ApacheCN, age=11.00, url=www.ada.com
    //原始值输出
    println(raw"name=${name}, age=${age}%.2f, url=${url}") //name=ApacheCN, age=11%.2f, url=www.ada.com
    println()

    //单行注释

    /*
    多行注释
     */

    /**
      * doc注释
      */

    //算术运算符
    var r1: Int = 10 / 3
    println("r1=" + r1) //3
    var r2: Double = 10 / 3
    println("r2=" + r2) //3.0
    var r3: Double = 10.0 / 3
    println("r3=" + r3) //3.3333333333333335
    println("r3=" + r3.formatted("%.2f")) //3.33
    println()

    println(10 % 3) //1
    println(-10 % 3) //-1
    println(10 % -3) //1
    println(-10 % -3) //-1
    println()

    //关系运算符
    var a = 9
    var b = 8
    println(a > b)
    println(a >= b)
    println(a <= b)
    println(a < b)
    println(a == b)
    println(a != b)
    var flag = a > b
    println(flag)

    println()
    var sumVal = 60
    var result =
      if (sumVal > 20) {
        "结果大于20"
      }
    println(result)
    println()

    for (i <- 1 to 10 if (i != 4 && i != 5)) {
      print(i + " ")
    }
    println()
    println()

    def f1(): Int = {
      100
    }

    println(f1) //100

    var f2 = f1
    var f3 = f1 _

    println(f2) //100

    // 打印的是100吗?
    println(f3) //<function0>

    // 如果要打印f3函数的返回值
    println(f3()) //100
    println()


    var money = 100

    def buy(): Int = {
      money -= 10
      money
    }

    def test1(a: Int) = {
      println(a)
      println(a)
    }

    def test2(a: => Int) = {
      println(a)
      println(a)
    }

    //    def main(args: Array[String]): Unit = {
    //      test1(buy)
    //      test2(buy)
    //    }

    // 函数的第一个参数类型是另一个函数
    def apply(f: Int => String, v: Int) = f(v)

    def fmtInt(n: Int): String = "[整数值{" + n + "}]"

    //    def main(args: Array[String]): Unit = {
    //      println(apply(fmtInt, 1200))
    //    }


    // 函数的返回值是一个函数
    def addBy(n: Int) = {
      (d: Double) => n + d
    }

    def main(args: Array[String]): Unit = {
      println(addBy(50)(80.223))
    }


  }

  def f8(n: Int): Int = {
    if (n <= 0) 1 else n * f8(n - 1)
  }
}

object Temp {
  def main(args: Array[String]): Unit = {
    def test1(x: Double) = {
      (y: Double) => x * x * y
    }

    var res = test1(2.0)(3.0)
    println(s"res=${res}")
  }
}

object Curry {
  // 原始函数, 有3个参数的函数
  def addMulti(a: Int, b: Int, c: Int) = (a + b) * c

  // 函数A的返回值是一个函数B, 函数B的返回值是函数C
  def addMulti(a: Int) = {
    (b: Int) => (c: Int) => (a + b) * c
  }

  def main(args: Array[String]): Unit = {
    println(addMulti(50)(80)(20))



    //方式2：使用稍微高级的用法(隐式类)：形式为 str.方法()
    //我们认为比较字符串是否相等是两件事，先转成小写[函数]， 再比较是否相等[函数]

    def eq(s1: String, s2: String): Boolean = {
      s1.equals(s2)
    }

    implicit class TestEq(s: String) {
      def checkEq(ss: String)(f: (String, String) => Boolean): Boolean = {
        f(s.toLowerCase, ss.toLowerCase)
      }
    }

//    str1.checkEq(str2)(_.equals(_))
  }

//  def main(args: Array[String]): Unit = {
//    val res = test()
//    println(res.toString)
//  }

  def test(): Nothing = {
    throw new Exception("不对")
  }

//  def main(args: Array[String]): Unit = {
//    f11()
//  }

  @throws(classOf[NumberFormatException])
  def f11() = {
    "abc".toInt
  }
}

